package mini.statement;


import java.util.HashMap;
import java.util.LinkedList;

import mini.Proc;
import mini.compiler.CodeGenerator;
import mini.expr.Expr;
import mini.util.SymbolicNames;

public class ReturnStatement extends Statement {

    private Expr expr;

    public ReturnStatement(Expr e) {
        expr = e;
    }

    public void eval(HashMap<String, Integer> nametable, HashMap<String, Proc> functiontable, LinkedList var)  {
        //Java can't throw exceptions of numbers, so we'll convert it to a string
        //and then on the other end we'll reconvert back to Integer..
        throw new IllegalStateException(Integer.toString(expr.eval(nametable, functiontable, var)));
    }
    
    @Override
    public String parse(HashMap<String,Integer> hm, HashMap<String, Proc> functiontable, LinkedList var) {
    	CodeGenerator cg = new CodeGenerator();
    	
    	//1. store return value in activation record
    	// Compute return value
    	cg.appendCode( expr.parse(hm, functiontable, var));
    	
    	// Put the address where to store it (the return value) into the Scratch
        cg.addLoadAccumulator(SymbolicNames.getSymbolicNameForSP());
        cg.addSubtract(SymbolicNames.getSymbolicNameForInteger(hm,2));
        cg.addStoreAccumulator(SymbolicNames.getSymbolicNameForScratch());
    	
    	// Load its value into the accumulator
    	cg.addLoadAccumulator( expr.getTempVariable() );
    	
    	//store that value from the accumulator into the return space, 
    	cg.addStoreIndirect( SymbolicNames.getSymbolicNameForScratch() );
    	
    	//2. Jump to RA
    	cg.addLoadIndirect( SymbolicNames.getSymbolicNameForSP() );				// Accum now has the RA in it
    	cg.addStoreAccumulator( SymbolicNames.getSymbolicNameForScratch() );	// Scratch now has the RA in it
    	cg.addJMI(SymbolicNames.getSymbolicNameForScratch());					// Jump to that address
    	
    	// And we're done
		return cg.getCode();

    }
}
